package com.unknowpupil.web.utils;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @Classname: DateUtils
 * @Author: <a> w10g </a>
 * @CreateDate: Create in 2019/10/8 17:21
 * @Description:
 * @Version: 1.0
 */
public class DateUtils {
    /**
     * The constant STANDARD_FORMAT.
     *
     * @desc 格式化 标准时间
     */
    public static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /**
     * The constant YEAR_MONTH_DAY_FORMAT.
     *
     * @desc 格式化年月日
     */
    public static final String YEAR_MONTH_DAY_FORMAT = "yyyy-MM-dd";


    /**
     * Srt to date date.
     *
     * @param dateTime  the date time
     * @param formatStr the format str
     * @return the date
     */
    public static Date srtToDate(String dateTime, String formatStr) {
        DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern(formatStr);
        DateTime dateTimes = dateTimeFormat.parseDateTime(dateTime);
        return dateTimes.toDate();

    }

    /**
     * Date to str string.
     *
     * @param date      the date
     * @param formatStr the format str
     * @return the string
     */
    public static String dateToStr(Date date, String formatStr) {
        if (date == null) {
            return "";
        }
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(formatStr);

    }


    /**
     * Srt to date date.
     *
     * @param dateTime the date time
     * @return the date
     */
    public static Date srtToDate(String dateTime) {
        DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern(STANDARD_FORMAT);
        DateTime dateTimes = dateTimeFormat.parseDateTime(dateTime);
        return dateTimes.toDate();

    }

    /**
     * Date to str string.
     *
     * @param date the date
     * @return the string
     */
    public static String dateToStr(Date date) {
        if (date == null) {
            return "";
        }
        DateTime dateTime = new DateTime(date);

        return dateTime.toString(STANDARD_FORMAT);

    }


    /**
     * 将时间转换为时间戳
     *
     * @param s the s
     * @return long long
     * @throws ParseException the parse exception
     */
    public static Long dateToStamp(String s) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(STANDARD_FORMAT);
        Date date = simpleDateFormat.parse(s);
        return date.getTime();
    }

    /**
     * 将时间戳转换为时间
     *
     * @param s the s
     * @return string string
     */
    public static String stampToDate(String s) {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(STANDARD_FORMAT);
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    /**
     * Gets week of year.
     *
     * @param date the date
     * @return the week of year
     * @desc 获取当前时间所在年的周数
     */
    public static int getWeekOfYear(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setMinimalDaysInFirstWeek(7);
        c.setTime(date);

        return c.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * Gets max week num of year.
     *
     * @param year the year
     * @return the max week num of year
     * @desc 获取当前时间所在年的最大周数
     */
    public static int getMaxWeekNumOfYear(int year) {
        Calendar c = new GregorianCalendar();
        c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);

        return getWeekOfYear(c.getTime());
    }


    /**
     * Gets first day of week.
     *
     * @param date the date
     * @return the first day of week
     * @desc 获取当前时间所在周的开始日期
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
        return c.getTime();
    }

    /**
     * Gets last day of week.
     *
     * @param date the date
     * @return the last day of week
     * @desc 获取当前时间所在周的结束日期
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
        return c.getTime();
    }


    /**
     * 获取几年后时间
     *
     * @param year the year
     * @param date the date
     * @return After year
     */
    public static Date getAfterYear(Integer year, Date date) {
        Calendar cal = Calendar.getInstance();
        /**
         *@desc 设置起时间
         */
        cal.setTime(date);
        /**
         *@desc 增加年数
         */
        cal.add(Calendar.YEAR, year);
        return cal.getTime();
    }

    /**
     * Gets before year.
     *
     * @param year the year
     * @param date the date
     * @return the before year
     * @desc 获取几年前时间
     */
    public static Date getBeforeYear(Integer year, Date date) {
        Calendar cal = Calendar.getInstance();
        /**
         *@desc 设置起时间
         */
        cal.setTime(date);
        /**
         *@desc 增加年数
         */
        cal.add(Calendar.YEAR, -year);
        return cal.getTime();
    }

    /**
     * 获取几秒后的时间
     *
     * @param second the second
     * @param date   the date
     * @return After second
     */
    public static Date getAfterSecond(Integer second, Date date) {
        Calendar cal = Calendar.getInstance();
        /**
         *@desc 设置起时间
         */
        cal.setTime(date);
        /**
         *@desc 增加秒
         */
        cal.add(Calendar.SECOND, second);
        return cal.getTime();
    }

    /**
     * Gets before second.
     *
     * @param second the second
     * @param date   the date
     * @return the before second
     * @desc 获取几秒前的时间
     */
    public static Date getBeforeSecond(Integer second, Date date) {
        Calendar cal = Calendar.getInstance();
        /**
         *@desc 设置起时间
         */
        cal.setTime(date);
        /**
         *@desc 增加秒
         */
        cal.add(Calendar.SECOND, -second);
        return cal.getTime();
    }

    /**
     * 获取几分钟后时间
     *
     * @param second the second
     * @param date   the date
     * @return After minute
     */
    public static Date getAfterMinute(Integer second, Date date) {
        Calendar cal = Calendar.getInstance();
        /**
         *@desc 设置起时间
         */
        cal.setTime(date);
        /**
         *@desc 增加秒速
         */
        cal.add(Calendar.MINUTE, second);
        return cal.getTime();
    }

    /**
     * Gets before minute.
     *
     * @param second the second
     * @param date   the date
     * @return the before minute
     * @desc 获取几分钟前时间
     */
    public static Date getBeforeMinute(Integer second, Date date) {
        Calendar cal = Calendar.getInstance();
        /**
         *@desc 设置起时间
         */
        cal.setTime(date);
        /**
         *@desc 减少秒速
         */
        cal.add(Calendar.MINUTE, -second);
        return cal.getTime();
    }


    /**
     * 获取当前月份第一天
     *
     * @param date the date
     * @return first day
     */
    public static Date getFirstDay(Date date) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        return cale.getTime();
    }

    /**
     * 获取几小时前的时间
     *
     * @param data the data
     * @param hour the hour
     * @return before hour
     */
    public static Date getBeforeHour(Date data, Integer hour) {
        Calendar c = Calendar.getInstance();
        c.setTime(data);
        c.set(Calendar.HOUR_OF_DAY, c.get(Calendar.HOUR_OF_DAY) - hour);
        return c.getTime();
    }

    /**
     * Gets After hour.
     *
     * @param data the data
     * @param hour the hour
     * @return the After hour
     * @desc 获取几小时后的时间
     */
    public static Date getAfterHour(Date data, Integer hour) {
        Calendar c = Calendar.getInstance();
        c.setTime(data);
        c.set(Calendar.HOUR_OF_DAY, c.get(Calendar.HOUR_OF_DAY) + hour);
        return c.getTime();
    }

    /**
     * 获取月份最后一天
     *
     * @param date the date
     * @return last day
     */
    public static Date getLastDay(Date date) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        return cale.getTime();
    }


    /**
     * Gets After day.
     *
     * @param day  the day
     * @param date the date
     * @return the After day
     * @desc 获取几天后的时间
     */
    public static Date getAfterDay(Integer day, Date date) {
        Calendar cal = Calendar.getInstance();
        /**
         *@desc 设置起时间
         */
        cal.setTime(date);
        /**
         *@desc 增加天数
         */
        cal.add(Calendar.DATE, day);
        return cal.getTime();
    }

    /**
     * Gets before day.
     *
     * @param day  the day
     * @param date the date
     * @return the before day
     * @desc 获取几天后的时间
     */
    public static Date getBeforeDay(Integer day, Date date) {
        Calendar cal = Calendar.getInstance();
        /**
         *@desc 设置起时间
         */
        cal.setTime(date);
        /**
         *@desc 减少天数
         */
        cal.add(Calendar.DATE, -day);
        return cal.getTime();
    }


    /**
     * 获取该月最后一天结束时间
     *
     * @param date the date
     * @return month last day
     */
    public static Date getMonthLastDay(Date date) {
        String eTime  = DateUtils.dateToStr(DateUtils.getLastDay(date), YEAR_MONTH_DAY_FORMAT);
        eTime = eTime + " 23:59:59";
        return srtToDate(eTime);
    }

    /**
     * 获取该月第一天开始时间
     *
     * @param date the date
     * @return month first day
     */
    public static Date getMonthFirstDay(Date date) {
        String sTime = DateUtils.dateToStr(DateUtils.getFirstDay(date), YEAR_MONTH_DAY_FORMAT);
        sTime = sTime + " 00:00:00";
        return srtToDate(sTime);
    }


    /**
     * 获取上个月最后一天结束时间
     *
     * @param date the date
     * @return before month last day
     */
    public static Date getBeforeMonthLastDay(Date date) {
        Calendar c = new GregorianCalendar();
        c.setTime(date);
        c.add(Calendar.MONTH, -1);
        return getMonthLastDay(c.getTime());
    }

    /**
     * 获取上个月第一天开始时间
     *
     * @param date the date
     * @return before month first day
     */
    public static Date getBeforeMonthFirstDay(Date date) {
        Calendar c = new GregorianCalendar();
        c.setTime(date);
        c.add(Calendar.MONTH, -1);
        return getMonthFirstDay(c.getTime());
    }

    /**
     * Gets today last time.
     *
     * @param date the date
     * @return the today last time
     * @desc 获取时间开始时间
     */
    public static Date getTodayLastTime(Date date) {
        String eTime  = DateUtils.dateToStr(date, YEAR_MONTH_DAY_FORMAT);
        eTime = eTime + " 23:59:59";
        return srtToDate(eTime);
    }

    /**
     * Gets today first time.
     *
     * @param date the date
     * @return the today first time
     * @desc 获取时间结束时间
     */
    public static Date getTodayFirstTime(Date date) {
        String eTime  = DateUtils.dateToStr(date, YEAR_MONTH_DAY_FORMAT);
        eTime = eTime + " 00:00:00";
        return srtToDate(eTime);
    }

    /**
     * 获取时间差 返回秒
     *
     * @param overTime
     * @return
     */
    public static Long laveTime(Date overTime) {
        if (overTime.getTime() <= System.currentTimeMillis()) {
            return 0L;
        }
        return (overTime.getTime() - System.currentTimeMillis()) / 1000;
    }

    /**
     * 比较两个日期之间的大小
     *
     * @param d1
     * @param d2
     * @return 前者大于后者返回true 反之false
     */
    public static boolean compareDate(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);

        int result = c1.compareTo(c2);
        if (result >= 0) {
            return true;
        } else {
            return false;
        }
    }

}
